//=============================================================================
#include "CVector.h"

//=============================================================================
CVector::CVector() {
    X = Y = Z = 0;
}

//-----------------------------------------------------------------------------
CVector::CVector(float X, float Y, float Z) {
    this->X = X;
    this->Y = Y;
    this->Z = Z;
}

//=============================================================================
bool CVector::operator==(CVector Vector) {
    return (this->X == Vector.X && this->Y == Vector.Y && this->X == Vector.Z);
}

//-----------------------------------------------------------------------------
bool CVector::operator!=(CVector Vector) {
    return !(this->X == Vector.X && this->Y == Vector.Y && this->X == Vector.Z);
}

//=============================================================================
CVector CVector::operator+(CVector Vector) {
    CVector TempVector;

    TempVector.X = this->X + Vector.X;
    TempVector.Y = this->Y + Vector.Y;
    TempVector.Z = this->Z + Vector.Z;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator-(CVector Vector) {
    CVector TempVector;

    TempVector.X = this->X - Vector.X;
    TempVector.Y = this->Y - Vector.Y;
    TempVector.Z = this->Z - Vector.Z;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator/(CVector Vector) {
    CVector TempVector;

    TempVector.X = this->X / Vector.X;
    TempVector.Y = this->Y / Vector.Y;
    TempVector.Z = this->Z / Vector.Z;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator*(CVector Vector) {
    CVector TempVector;

    TempVector.X = this->X * Vector.X;
    TempVector.Y = this->Y * Vector.Y;
    TempVector.Z = this->Z * Vector.Z;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator+(float Value) {
    CVector TempVector;

    TempVector.X = this->X + Value;
    TempVector.Y = this->Y + Value;
    TempVector.Z = this->Z + Value;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator-(float Value) {
    CVector TempVector;

    TempVector.X = this->X - Value;
    TempVector.Y = this->Y - Value;
    TempVector.Z = this->Z - Value;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator/(float Value) {
    CVector TempVector;

    TempVector.X = this->X / Value;
    TempVector.Y = this->Y / Value;
    TempVector.Z = this->Z / Value;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::operator*(float Value) {
    CVector TempVector;

    TempVector.X = this->X * Value;
    TempVector.Y = this->Y * Value;
    TempVector.Z = this->Z * Value;

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::Copy() {
    CVector TempVector;

    TempVector.X = this->X;
    TempVector.Y = this->Y;
    TempVector.Z = this->Z;

    return TempVector;
}

//-----------------------------------------------------------------------------
void CVector::Normalize() {
    double Mag = Magnitude();

    this->X /= Mag;
    this->Y /= Mag;
    this->Z /= Mag;
}

//-----------------------------------------------------------------------------
double CVector::Magnitude() {
    return sqrt((X * X) + (Y * Y) + (Z * Z));
}

//-----------------------------------------------------------------------------
double CVector::Distance(CVector Vector) {
    return sqrt(pow(X - Vector.X, 2) + pow(Y - Vector.Y, 2) + pow(Z - Vector.Z, 2));
}

//-----------------------------------------------------------------------------
double CVector::DotProduct(CVector Vector) {
    return (this->X * Vector.X) + (this->Y * Vector.Y) + (this->Z * Vector.Z);
}

//-----------------------------------------------------------------------------
CVector CVector::CrossProduct(CVector Vector) {
    CVector TempVector;

    TempVector.X = (this->Y * Vector.Z) - (this->Z * Vector.Y);
    TempVector.Y = (this->Z * Vector.X) - (this->X * Vector.Z);
    TempVector.Z = (this->X * Vector.Y) - (this->Y * Vector.X);

    return TempVector;
}

//-----------------------------------------------------------------------------
CVector CVector::RayIntersectPlane(CVector Origin, CVector PlaneNormal) {
    CVector Vector;

    Vector = (Vector - (PlaneNormal.DotProduct(Origin)) / this->DotProduct(PlaneNormal));
    Vector = Vector * -1;

    return Vector;
}

//=============================================================================
